package cn.com.ourclass.webviewnew.web;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.WindowManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.hc.framework.log.LogUtils;
import com.tencent.sonic.sdk.SonicCacheInterceptor;
import com.tencent.sonic.sdk.SonicConfig;
import com.tencent.sonic.sdk.SonicConstants;
import com.tencent.sonic.sdk.SonicEngine;
import com.tencent.sonic.sdk.SonicSession;
import com.tencent.sonic.sdk.SonicSessionConfig;
import com.tencent.sonic.sdk.SonicSessionConnection;
import com.tencent.sonic.sdk.SonicSessionConnectionInterceptor;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.com.ourclass.webviewnew.R;
import cn.com.ourclass.webviewnew.web.client.MyWebViewClient;
import cn.com.ourclass.webviewnew.web.client.MyWebViewInterface;
import cn.com.ourclass.webviewnew.web.js.MiniwebInterface;
import cn.com.ourclass.webviewnew.web.sonic.SonicJavaScriptInterface;
import cn.com.ourclass.webviewnew.web.sonic.SonicRuntimeImpl;
import cn.com.ourclass.webviewnew.web.sonic.SonicSessionClientImpl;
import cn.com.ourclass.webviewnew.web.client.MyWebViewInterface;
import cn.com.ourclass.webviewnew.web.tools.PhotoSelectActivity;
import qiu.niorgai.StatusBarCompat;

/**
 * Created by HuHaiqin on 2017/11/16.
 */

public class WebViewNewActivity extends AppCompatActivity implements MyWebViewInterface {


    public final static String PARAM_URL = "param_url";
    public final static String PARAM_MODE = "param_mode";
    public static final int MODE_DEFAULT = 0;
    public static final int MODE_SONIC = 1;
    public static final int MODE_SONIC_WITH_OFFLINE_CACHE = 2;
    private static final int PERMISSION_REQUEST_CODE_STORAGE = 1;

    private WebView webView;
    public SonicSession sonicSession;
    private Context mActivity = this;
    SonicSessionClientImpl sonicSessionClient;

    String url;
    int mode;
    Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        intent = getIntent();
        url = intent.getStringExtra(PARAM_URL);
        String statusBarColor = intent.getStringExtra("statusBarColor");
        if(statusBarColor.equals("")){
            statusBarColor = "#333333";
        }
        mode = intent.getIntExtra(PARAM_MODE, -1);
        if (TextUtils.isEmpty(url) || -1 == mode) {
            finish();
            return;
        }

        check();//权限处理
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); //全屏
        initSonic(); //初始化Sonic
        setContentView(R.layout.activity_browser);
        setStatusBar(statusBarColor,false);
        initWebView(); //初始化WebView组件
    }

    public static void loadUrl(Context mContext,String url,String statusBarColor) {
        Intent intent = new Intent(mContext, WebViewNewActivity.class);
        intent.putExtra(PARAM_URL, url);
        intent.putExtra(PARAM_MODE, MODE_SONIC);
        intent.putExtra("statusBarColor",statusBarColor); //状态栏颜色
        intent.putExtra(SonicJavaScriptInterface.PARAM_CLICK_TIME, System.currentTimeMillis());
        //startActivityForResult(intent, -1);
        mContext.startActivity(intent);
    }

    public void initWebView(){
        // init webview
        webView = (WebView) findViewById(R.id.webview);
        webView.setWebViewClient(new MyWebViewClient(this));

        WebSettings webSettings = webView.getSettings();

        // add java script interface
        // note:if api level lower than 17(android 4.2), addJavascriptInterface has security
        // issue, please use x5 or see https://developer.android.com/reference/android/webkit/
        // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)
        webSettings.setJavaScriptEnabled(true);
        webView.removeJavascriptInterface("searchBoxJavaBridge_");
        intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis());
        webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), "sonic");
        // 与js交互
        webView.addJavascriptInterface(new MiniwebInterface(this), "miniweb");

        // init webview settings
        webSettings.setAllowContentAccess(true);
        webSettings.setDatabaseEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAppCacheEnabled(true);
        webSettings.setSavePassword(false);
        webSettings.setSaveFormData(false);
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);


        // webview is ready now, just tell session client to bind
        if (sonicSessionClient != null) {
            sonicSessionClient.bindWebView(webView);
            sonicSessionClient.clientReady();
        } else { // default mode
            webView.loadUrl(url);
        }
    }

    public void initSonic(){
        // init sonic engine if necessary, or maybe u can do this when application created
        if (!SonicEngine.isGetInstanceAllowed()) {
            SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());
        }

        sonicSessionClient = null;

        // if it's sonic mode , startup sonic session at first time
        if (MODE_DEFAULT != mode) { // sonic mode
            SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();
            sessionConfigBuilder.setSupportLocalServer(true);

            // if it's offline pkg mode, we need to intercept the session connection
            if (MODE_SONIC_WITH_OFFLINE_CACHE == mode) {
                sessionConfigBuilder.setCacheInterceptor(new SonicCacheInterceptor(null) {
                    @Override
                    public String getCacheData(SonicSession session) {
                        return null; // offline pkg does not need cache
                    }
                });

                sessionConfigBuilder.setConnectionInterceptor(new SonicSessionConnectionInterceptor() {
                    @Override
                    public SonicSessionConnection getConnection(SonicSession session, Intent intent) {
                        return new OfflinePkgSessionConnection(WebViewNewActivity.this, session, intent);
                    }
                });
            }

            // create sonic session and run sonic flow
            sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build());
            if (null != sonicSession) {
                sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());
            } else {
                // this only happen when a same sonic session is already running,
                // u can comment following codes to feedback as a default mode.
                // throw new UnknownError("create session fail!");
                //Toast.makeText(this, "create sonic session fail!", Toast.LENGTH_LONG).show();
            }
        }
    }

    /**
     * 处理权限
     */
    public void check(){
        //检测权限，再初始化
        if (hasPermission()) {
            init();
        } else {
            requestPermission();
        }
    }

    private void init() {
        // init sonic engine
        if (!SonicEngine.isGetInstanceAllowed()) {
            SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());
        }
    }

    private boolean hasPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
        }
        return true;
    }

    private void requestPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE_STORAGE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (PERMISSION_REQUEST_CODE_STORAGE == requestCode) {
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                requestPermission();
            } else {
                init();
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    @Override
    protected void onDestroy() {
        if (null != sonicSession) {
            sonicSession.destroy();
            sonicSession = null;
        }
        super.onDestroy();
    }

    @Override
    public void addImageClickListener() {
        webView.loadUrl("javascript:(function(){" +
                "var objs = document.getElementsByTagName(\"img\");" +
                "var imgs = \"\";" +
                "for(var i=0;i<objs.length;i++){" +
                "var obj = objs[i];" +
                "imgs += obj.getAttribute(\"src\")+\"#_#\";" +
                "}" +
                "for(var i=0;i<objs.length;i++){" +
                "objs[i].onclick=function(){" +
                "window.miniweb.imageClick(imgs,this.getAttribute(\"src\"));" +
                "}" +
                "}" +
                "})()");
    }

    private static class OfflinePkgSessionConnection extends SonicSessionConnection {

        private final WeakReference<Context> context;

        public OfflinePkgSessionConnection(Context context, SonicSession session, Intent intent) {
            super(session, intent);
            this.context = new WeakReference<Context>(context);
        }

        @Override
        protected int internalConnect() {
            Context ctx = context.get();
            if (null != ctx) {
                try {
                    InputStream offlineHtmlInputStream = ctx.getAssets().open("sonic-demo-index.html");
                    responseStream = new BufferedInputStream(offlineHtmlInputStream);
                    return SonicConstants.ERROR_CODE_SUCCESS;
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
            return SonicConstants.ERROR_CODE_UNKNOWN;
        }

        @Override
        protected BufferedInputStream internalGetResponseStream() {
            return responseStream;
        }

        @Override
        public void disconnect() {
            if (null != responseStream) {
                try {
                    responseStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public int getResponseCode() {
            return 200;
        }

        @Override
        public Map<String, List<String>> getResponseHeaderFields() {
            return new HashMap<>(0);
        }

        @Override
        public String getResponseHeaderField(String key) {
            return "";
        }
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode,resultCode,data);
        IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode,resultCode,data);
        if(intentResult != null) {
            if(intentResult.getContents() == null) {

            } else {
                // scanResult 为 获取到的二维码扫描的字符串
                String scanResult = intentResult.getContents();
                //Toast.makeText(this,"扫描成功"+scanResult,Toast.LENGTH_LONG).show();
                //webView.loadUrl("javascript:getScanResult(\"fadfsdfsadfdfasdfasdfadsfdasf\");");
                //webView.loadUrl("javascript:getScanResult(\""+scanResult+"\");");
                webView.loadUrl("javascript:layui.use(['jquery'],function(){" +
                        "getScanResult(\""+scanResult+"\");"+
                        "})");
            }
        } else {
            if(resultCode == RESULT_OK) {
                switch (requestCode) {
                    case PhotoSelectActivity.REQUEST_PHOTO_CODE:
                        String result = data.getStringExtra("result");
                        webView.loadUrl("javascript:layui.use(['jquery'],function(){" +
                                "getUploadResult(\""+result+"\");"+
                                "})");
                        break;
                }
            }
        }
    }

    public void close(){
        finish(); //关闭
    }

    public void setStatusBar( String colorStr, boolean isHide) {
        //修改状态栏颜色
        StatusBarCompat.setStatusBarColor(this, Color.parseColor(colorStr));
        if(isHide){
            StatusBarCompat.translucentStatusBar(this);
        }

    }
}
